home *** CD-ROM | disk | FTP | other *** search
/ Aminet 32 / Aminet 32 (1999)(Schatztruhe)[!][Aug 1999].iso / Aminet / dev / c / SUPRALib.lha / SUPRALib / Developer / Source.ORG / RecDirNext.c < prev    next >
C/C++ Source or Header  |  1999-05-17  |  8KB  |  219 lines

  1. /****** RecDirNext ***************************************************
  2. *
  3. *   NAME
  4. *       RecDirNext -- Gets information about the next file (V10)
  5. *       (dos V36)
  6. *
  7. *   SYNOPSIS
  8. *       error = RecDirNext(RecDirInfo, RecDirFIB);
  9. *
  10. *       UBYTE = RecDirNext(struct RecDirInfo *, struct RecDirFIB *);
  11. *
  12. *   FUNCTION
  13. *       Retrieves information about the next file in a scanning process.
  14. *       Calling this function  will not provide a list of sorted files
  15. *       niether by ASCII order nor by directory levels. That means
  16. *       it will scan files as they have been stored on a disk drive.
  17. *
  18. *       The main advantage of using this function from using ExNext()
  19. *       is that you don't have to program a recursive scanning routine
  20. *       by yourself. You need only to provide lowest directory path,
  21. *       how deep into subdirectories you want to scan, and which
  22. *       information about files you need to be provided with.
  23. *       RecDirNext() will only return files but no directories.
  24. *       You are also able to select a matching pattern so that only
  25. *       files which match it will be returned.
  26. *
  27. *       Please see RecDirInit() for more info.
  28. *
  29. *   INPUTS
  30. *       RecDirInfo - pointer to RecDirInfo structure. You MUST call
  31. *       RecDirInit(), providing it with this structure, before calling
  32. *       any RecDirNext() function.
  33. *
  34. *       RecDirFIB - pointer to RecDirFIB structure which should be
  35. *       previousely allocated. You only set those fields in the
  36. *       structure that you want to have information about. Any field
  37. *       should point to a variable into which information will be stored.
  38. *       Check "struct RecDirFIB" to see what each field mean.
  39. *       All field in RecDirFIB structure that are set to NULL will be
  40. *       ignored.
  41. *
  42. *   RESULT
  43. *       error - zero if no error. Otherwise one of the following:
  44. *           DN_ERR_END - scanning is completed. You should not call
  45. *                        any RecDirNext() again.
  46. *           DN_ERR_EXAMINE - Failure while examining a file.
  47. *           DN_ERR_MEM - not enough memory available to complete
  48. *                        the operation.
  49. *           IF any error will be resulted, RecDirFree will be called
  50. *           internally.
  51. *
  52. *
  53. *   EXAMPLE
  54. *       This example will scan through the entire HD0: disk device, and
  55. *       will print for each file: its dir path, its name, its size.
  56. *
  57. *
  58. *   #include <stdio.h>
  59. *   #include <stdlib.h>
  60. *   #include <clib/exec_protos.h>
  61. *   #include <clib/dos_protos.h>
  62. *   #include <libraries/supra.h>
  63. *
  64. *   struct RecDirFIB rdf;
  65. *   struct RecDirInfo rdi;
  66. *   char name[30];
  67. *   char path[100];
  68. *   LONG size;
  69. *   LONG err;
  70. *
  71. *   struct DosBase *DosBase;
  72. *
  73. *   void main()
  74. *   {
  75. *        if (DosBase = (struct DosBase *)OpenLibrary("dos.library",0)) {
  76. *
  77. *           rdi.rdi_Path = "RAM:";  \* from path "RAM:" *\
  78. *           rdi.rdi_Num = -1;       \* Unlimited subdirs deep *\
  79. *           rdi.rdi_Pattern = NULL; \* Don't match files for pattern *\
  80. *
  81. *           if (RecDirInit(&rdi) == 0) {
  82. *               rdf.Path = path;  \* We want to get files' path, name and size *\
  83. *               rdf.Name = name;
  84. *               rdf.Size = &size;
  85. *               while ((err = RecDirNext(&rdi, &rdf)) == 0) {
  86. *                   printf("%s (%s) %ld\n", path, name, size);
  87. *               }
  88. *
  89. *               \* Now check if DN_ERR_END or some other unexpected error *\
  90. *               switch (err) {
  91. *                   case DN_ERR_END:
  92. *                       printf("Scanning completed\n");
  93. *                       break;
  94. *                   case DN_ERR_EXAMINE:
  95. *                       printf("Error: trouble examining a file\n");
  96. *                       break;
  97. *                   case DN_ERR_MEM:
  98. *                       printf("Error: not enough memory\n");
  99. *               }
  100. *           }
  101. *
  102. *           CloseLibrary((struct Library *)DosBase);
  103. *       } else printf("Cannot open dos.library\n");
  104. *   }
  105. *
  106. *
  107. *   NOTES
  108. *       If you want to end scanning earlier you have to call RecDirFree()!
  109. *
  110. *   BUGS
  111. *       none found
  112. *
  113. *   SEE ALSO
  114. *       RecDirInit(), RecDirTags(), RecDirFree(), libraries/supra.h
  115. *
  116. **************************************************************************/
  117.  
  118. #include <proto/exec.h>
  119. #include <proto/dos.h>
  120. #include <exec/memory.h>
  121. #include <dos/dos.h>
  122. #include <string.h>
  123. #include <libraries/supra.h>
  124.  
  125. UBYTE RecDirNext(struct RecDirInfo *rdi, struct RecDirFIB *rdf)
  126. {
  127.     struct LockNode *ln,*newln;
  128.     struct FileInfoBlock *fib;
  129.     BPTR lock=0;
  130.     int len;
  131.     char *path;
  132.     int repeat;
  133.  
  134. do {
  135.     repeat = FALSE;
  136.     ln = rdi->rdi_Node;
  137.     fib = ln->ln_FIB;
  138.  
  139.     if (ExNext(ln->ln_Lock, fib)) {
  140.         len = strlen(ln->ln_Path)+strlen(fib->fib_FileName);
  141.         if (fib->fib_DirEntryType < 0) {   /* This is a file */
  142.            if (rdi->rdi_Pattern==NULL || MatchPattern(rdi->rdi_Pattern, fib->fib_FileName)) {
  143.             /* Start filling the RecDirFIB structure */
  144.             if (rdf->Name) strcpy(rdf->Name, fib->fib_FileName);
  145.             if (rdf->Path) strcpy(rdf->Path, ln->ln_Path);
  146.             if (rdf->Full) {
  147.                 strcpy(rdf->Full, ln->ln_Path);
  148.                 strcat(rdf->Full, fib->fib_FileName);
  149.                 }
  150.             if (rdf->Size) *rdf->Size = fib->fib_Size;
  151.             if (rdf->Flags) *rdf->Flags = fib->fib_Protection;
  152.             if (rdf->Comment) strcpy(rdf->Comment, fib->fib_Comment);
  153.             if (rdf->Date) memcpy(rdf->Date, &fib->fib_Date, sizeof(struct DateStamp));
  154.             if (rdf->Blocks) *rdf->Blocks = fib->fib_NumBlocks;
  155.             if (rdf->UID) *rdf->UID = fib->fib_OwnerUID;
  156.             if (rdf->GID) *rdf->GID = fib->fib_OwnerGID;
  157.             if (rdf->FIB) memcpy(rdf->FIB, fib, sizeof(struct FileInfoBlock));
  158.             return(0L);
  159.            } /* Pattern matched */
  160.             repeat = TRUE; /* Pattern not matched */
  161.         } else if (rdi->rdi_Deep < rdi->rdi_Num || rdi->rdi_Num == -1) {    /* This is a directory */
  162.             if (path = AllocMem(len+2,0)) {
  163.                 strcpy(path, ln->ln_Path);
  164.                 strcat(path, fib->fib_FileName);
  165.                 strcat(path, "/");
  166.  
  167.                 fib = NULL;
  168.  
  169.                 if (lock = Lock(path, ACCESS_READ)) {
  170.                     if (fib = AllocMem(sizeof(struct FileInfoBlock), 0L)) {
  171.                         if (Examine(lock, fib)) {
  172.                                 /* Set up a new LockNode */
  173.                             if (newln = AllocMem(sizeof(struct LockNode), 0L)) {
  174.                                 rdi->rdi_Deep++;
  175.                                 rdi->rdi_Node = newln;
  176.                                 ln->ln_Succ = newln;
  177.                                 newln->ln_Pred = ln;
  178.                                 newln->ln_Succ = NULL;
  179.                                 newln->ln_Lock = lock;
  180.                                 newln->ln_FIB  = fib;
  181.                                 newln->ln_Path = path;
  182.                                 newln->ln_Len  = len+2;
  183.                                 repeat = TRUE;
  184.                             }
  185.                         }
  186.                     }
  187.                 }
  188.             }
  189.  
  190.             if (repeat == FALSE) {  /* MEMORY ERROR! */
  191.                 if (fib) FreeMem(fib, sizeof(struct FileInfoBlock));
  192.                 if (lock) UnLock(lock);
  193.                 if (path) FreeMem(path, len+2);
  194.                 RecDirFree(rdi);
  195.                 return(DN_ERR_MEM);
  196.             }
  197.         } /*Examined file was file or dir */
  198.     } else { /* ExNext failed: probably no more files in current dir */
  199.         if (IoErr() != ERROR_NO_MORE_ENTRIES) { /* Something very wrong */
  200.             RecDirFree(rdi);
  201.             return(DN_ERR_EXAMINE);
  202.         } else { /* Erase last LockNode */
  203.             FreeMem(ln->ln_Path, ln->ln_Len);
  204.             FreeMem(ln->ln_FIB, sizeof(struct FileInfoBlock));
  205.             UnLock(ln->ln_Lock);
  206.             newln=ln->ln_Pred;
  207.             FreeMem(ln, sizeof(struct LockNode));
  208.             newln->ln_Succ = NULL;
  209.             rdi->rdi_Node = newln;
  210.             rdi->rdi_Deep--;
  211.             if (rdi->rdi_Deep == 0) return(DN_ERR_END);   /* Scanning complete */
  212.  
  213.             repeat = TRUE;
  214.        }
  215.    }
  216. } while (repeat == TRUE);
  217.  
  218. }
  219.